package com.agency.controller;

import cardval.dao.AdminDao;
import cardval.dao.PartnerDao;
import cardval.entity.Admin;
import cardval.entity.PartnerInfo;
import com.allo2o.common.VO.AgencyVO;
import com.allo2o.common.convertor.AgencyConvertor;
import com.allo2o.common.domain.SysParameter;
import com.allo2o.common.mapper.AgencyDOMapper;
import com.allo2o.common.mapper.SysParameterMapper;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.mvc.support.RedirectAttributesModelMap;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

/**
 * Created by Lu.Bing on 16-6-27.
 *
 * @author Lu.Bing
 */
@Controller
public class AgentController {

    private static final Logger LOGGER = LoggerFactory.getLogger(AgentController.class);

    @Resource
    private SysParameterMapper sysParameterMapper;

    @Resource
    private AgencyDOMapper agencyDOMapper;

    @Resource
    private PartnerDao partnerDao;

    @Resource
    private AdminDao adminDao;

    /**
     * <ul>
     * login
     * </ul>
     *
     * @return redirect to login page
     */
    @RequestMapping(value = "login.htm")
    public String login() {
        return "login";
    }

    /**
     * <ul>
     * <li>
     * 默认欢迎页
     * </li>
     * </ul>
     *
     * @return redirect to login page
     */
    @RequestMapping(value = "/")
    public String welcomePage() {
        return "login";
    }

    /**
     * <ul>
     * main.html
     * </ul>
     *
     * @return main page
     */
    @RequestMapping(value = "main.htm")
    public String mainPage(ModelMap modelMap, HttpServletRequest request) {
        modelMap.addAttribute("msger", StringUtils.isBlank(request.getParameter("msger")) ? "" : request.getParameter("msger"));
        return "main";
    }

    /**
     * <ul>
     * add an agent
     * set name, password ant other infos
     * upload pictures
     * </ul>
     *
     * @param request  HttpServletRequest
     * @param agencyVO agencyVO
     * @return success ? main page : error(500) page
     */
    @RequestMapping(value = "addAgent.htm", method = RequestMethod.POST)
    public String addAgent(HttpServletRequest request, @ModelAttribute AgencyVO agencyVO, RedirectAttributesModelMap redirectAttributesModelMap) {
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
        if (multipartResolver.isMultipart(request)) {
            Map<String, MultipartFile> fileMap = ((MultipartHttpServletRequest) request).getFileMap();
            Set<String> keys = fileMap.keySet();
            // 上传目录
            String proPath = request.getSession().getServletContext().getRealPath("/upload/");
            File uploadPath = new File(proPath);
            if (!uploadPath.exists()) {
                uploadPath.mkdir();
            }
            for (String key : keys) {
                MultipartFile file = fileMap.get(key);
                if (file != null) {
                    String myFileName = file.getOriginalFilename();
                    if (!Objects.equals(myFileName.trim(), "")) {
                        String fileName = "/" + file.getOriginalFilename();
                        String renamed = rename(fileName);
                        String path = proPath + renamed;
                        // 根据key设置agency对象的属性
                        if (StringUtils.equals(key, "bizLicenceFile")) {
                            agencyVO.setBizLicence("/upload" + renamed);
                        } else if (StringUtils.equals(key, "taxFile")) {
                            agencyVO.setTax("/upload" + renamed);
                        } else if (StringUtils.equals(key, "organizationFile")) {
                            agencyVO.setOrganization("/upload" + renamed);
                        } else if (StringUtils.equals(key, "idcardFrontFile")) {
                            agencyVO.setIdcardFront("/upload" + renamed);
                        } else if (StringUtils.equals(key, "idcardBackFile")) {
                            agencyVO.setIdcardBack("/upload" + renamed);
                        }

                        File localFile = new File(path);
                        try {
                            file.transferTo(localFile);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            agencyDOMapper.insert(AgencyConvertor.VO2DOConvert(agencyVO));
            redirectAttributesModelMap.addAttribute("msger", "<b>success</b>");
        }
        return "redirect:/main.htm";
    }

    /**
     * <ul>
     * rename file
     * </ul>
     *
     * @param fileName fileName
     * @return new random filename
     */
    private String rename(String fileName) {
        String ext;
        int pot = fileName.lastIndexOf(".");
        if (pot != -1) {
            ext = fileName.substring(pot);
        } else {
            ext = "";
        }
        return "/" + (UUID.randomUUID() + ext).toLowerCase();
    }

    /**
     * <ul>
     * setup agent profit rate
     * </ul>
     *
     * @return main page
     */
    @RequestMapping(value = "agentProfit.htm")
    public String agentProfit(HttpServletRequest request, RedirectAttributesModelMap redirectAttributesModelMap) {
        // 省代分润
        AgencyVO proVO = new AgencyVO();
        String proalipay = request.getParameter("proalipay");
        String prowechat = request.getParameter("prowechat");
        String prot1 = request.getParameter("prot1");
        String prod0 = request.getParameter("prod0");
        proVO.setAlipayRate(new BigDecimal(proalipay));
        proVO.setWechatRate(new BigDecimal(prowechat));
        proVO.setT1(new BigDecimal(prot1));
        proVO.setD0(new BigDecimal(prod0));

        // 市代分润
        AgencyVO cityVO = new AgencyVO();
        String cityalipay = request.getParameter("cityalipay");
        String citywechat = request.getParameter("citywechat");
        String cityt1 = request.getParameter("cityt1");
        String cityd0 = request.getParameter("cityd0");
        cityVO.setAlipayRate(new BigDecimal(cityalipay));
        cityVO.setWechatRate(new BigDecimal(citywechat));
        cityVO.setT1(new BigDecimal(cityt1));
        cityVO.setD0(new BigDecimal(cityd0));

        try {
            agencyDOMapper.updateCityProfit(AgencyConvertor.VO2DOConvert(cityVO));
            agencyDOMapper.updateProvProfit(AgencyConvertor.VO2DOConvert(proVO));
        } catch (Exception e) {
            LOGGER.error("修改费率失败", e);
            // 发生异常手动回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            redirectAttributesModelMap.addAttribute("msger", "<b>Failed</b>, All operations were RollBACKED!");
        }
        redirectAttributesModelMap.addAttribute("msger", "<b>success</b>");
        return "redirect:/main.htm";
    }

    /**
     * <ul>
     * modify pay rate
     * </ul>
     *
     * @param request httpServletRequest
     * @return main page
     */
    @RequestMapping(value = "updatePayRate.htm")
    public String updateTradeRate(HttpServletRequest request, RedirectAttributesModelMap redirectAttributesModelMap) {
        Enumeration paramNames = request.getParameterNames();
        while (paramNames.hasMoreElements()) {
            String paramName = (String) paramNames.nextElement();
            String[] paramValues = request.getParameterValues(paramName);
            if (paramValues.length == 1) {
                String paramValue = paramValues[0];
                if (paramValue.length() != 0) {
                    SysParameter sysParameter = new SysParameter();
                    sysParameter.setParamName(paramName.trim());
                    sysParameter.setParamValue(paramValue);
                    try {
                        sysParameterMapper.updateByParamName(sysParameter);
                    } catch (Exception e) {
                        LOGGER.error("修改收款费率失败", e);
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                        redirectAttributesModelMap.addAttribute("msger", "<b>Failed</b>, All operations were RollBACKED!");
                    }
                }
            }
        }
        redirectAttributesModelMap.addAttribute("msger", "<b>success</b>");
        return "redirect:/main.htm";
    }

    /**
     * <ul>根据市代的id, 生成注册二维码</ul>
     *
     * @param mobile   市代账号
     * @param request  httpServletRequest
     * @param response httpServletResopnse
     * @throws Exception exceptions
     */
    @RequestMapping(value = "viewQRCode.htm")
    public void viewQRCode(@RequestParam("mobile") String mobile, HttpServletRequest request, HttpServletResponse response) throws Exception {
        String path = "/merchant";
        String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
        String text = basePath + "invitePage.htm?agentId=" + mobile;

        String format = "png";
        int height = 300;
        int width = 300;
        Hashtable<EncodeHintType, String> hints = new Hashtable<>();
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, hints);
        MatrixToImageWriter.writeToStream(bitMatrix, format, response.getOutputStream());
        response.getOutputStream().flush();
        response.getOutputStream().close();
    }


    /**
     * <ul>
     * 登陆动作, 匹配用户名密码
     * </ul>
     *
     * @param mobile   用户名
     * @param password 密码
     * @return success ? main page : login page
     */
    @RequestMapping(value = "login.htm", method = RequestMethod.POST, params = "action")
    public String login(ModelMap modelMap, @RequestParam("mobile") String mobile,
                        @RequestParam("password") String password, HttpServletRequest request) {
        HttpSession sessoin = request.getSession(true);

        List<Admin> admins = adminDao.queryAdmin(mobile);

        if (!CollectionUtils.isEmpty(admins)) {
            Admin admin = admins.get(0);
            if (admin != null) {
                if (StringUtils.equals(password, admin.getPassword())) {
                    sessoin.setAttribute("isPartner", "0");
                    sessoin.setAttribute("current_user", mobile);
                    return "redirect:/main.htm";
                }
            }
        } else {
            List<PartnerInfo> partnerInfos = partnerDao.queryPartners(mobile);
            if (!CollectionUtils.isEmpty(partnerInfos)) {
                PartnerInfo partnerInfo = partnerInfos.get(0);
                if (partnerInfo != null) {
                    if (StringUtils.equals(password, partnerInfo.getPassword())) {
                        sessoin.setAttribute("isPartner", "1");
                        sessoin.setAttribute("current_user", mobile);
                        return "redirect:/main.htm";
                    }
                }
            }
        }
        modelMap.addAttribute("errormsg", "用户名或密码错误");
        return "login";
    }
}
